package com.cotasul.tela;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;

import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import com.cotasul.bean.CompradorBean;
import com.cotasul.bean.CotacaoBean;
import com.cotasul.bean.FormaPagamentoBean;
import com.cotasul.bean.FornecedorBean;
import com.cotasul.bean.ItemOrcamentoBean;
import com.cotasul.bean.OrcamentoBean;
import com.cotasul.bean.ProdutoBean;
import com.cotasul.bean.UsuarioBean;
import com.cotasul.negocio.CompradorServico;
import com.cotasul.negocio.CotacaoServico;
import com.cotasul.negocio.FormaPagamentoServico;
import com.cotasul.negocio.FornecedorServico;
import com.cotasul.negocio.OrcamentoServico;
import com.cotasul.negocio.ProdutoServico;
import com.cotasul.negocio.excecoes.EmailException;
import com.cotasul.negocio.interfaces.IServicoGenerico;
import com.cotasul.util.Ferramentas;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;

@ManagedBean
@SessionScoped
public class CotacaoTela extends TelaAbstrata {

	private List<OrcamentoBean> listaOrcamentos;

	private UsuarioBean usuario;

	private OrcamentoServico<OrcamentoBean> orcamentoServico;

	private String dataDe;

	private String dataAte;

	private String numero;

	private OrcamentoBean orcamento;

	@ManagedProperty(value = "#{fornecedorBean}")
	private FornecedorBean fornecedor;

	@ManagedProperty(value = "#{compradorBean}")
	private CompradorBean comprador;

	private CotacaoBean cotacao;

	private CotacaoServico<CotacaoBean> cotacaoServico;

	private FormaPagamentoServico<FormaPagamentoBean> formaServico;

	private ItemOrcamentoBean item;

	private StreamedContent imagemProduto;

	private String tipoFreteInput;

	private FacesMessage msg;

	private CompradorServico<CompradorBean> compradorServico;

	private Map<String, String> param;

	private CompradorBean compradorFiltro;

	private FornecedorBean fornecedorFiltro;

	private Date dataDeFiltro;

	private Date dataAteFiltro;

	private Long orcamentoFiltro;

	private String ordemFiltro;

	private ProdutoBean produtoFiltro;

	private String statusFiltro;

	private FornecedorServico<FornecedorBean> fornecedorServico;

	private ProdutoServico<ProdutoBean> produtoServico;

	public CotacaoTela() {
		try {
			usuario = usuario == null ? (UsuarioBean) ((HttpSession) FacesContext
					.getCurrentInstance().getExternalContext()
					.getSession(false)).getAttribute("usuario")
					: usuario;
			cotacao = new CotacaoBean();
			cotacaoServico = new CotacaoServico<CotacaoBean>();
			formaServico = new FormaPagamentoServico<FormaPagamentoBean>();
			produtoServico = new ProdutoServico<ProdutoBean>();
			compradorServico = new CompradorServico<CompradorBean>();
			orcamentoServico = new OrcamentoServico<OrcamentoBean>();
			fornecedorServico = new FornecedorServico<FornecedorBean>();
			param = new HashMap<String, String>();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void handleFileUpload(FileUploadEvent event) {
		try {
			cotacao.setImagemProd(event.getFile().getContents());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("rawtypes")
	protected IServicoGenerico getServico() {
		return this.cotacaoServico;
	}

	public void cotar() {
		cotacao.setFornecedor(fornecedor);
		cotacao.setItemOrcamento(item);
		cotacao.setFormaPagamento(FormaPagamentoModalPesquisaTela.forma);
		cotacao.setTipoFrete(tipoFreteInput);
		Map<String, Long> codigo;
		FacesMessage msg2 = null;
		try {
			codigo = cotacaoServico.salvar(cotacao);
			cotacao = new CotacaoBean();
			FormaPagamentoModalPesquisaTela.forma = new FormaPagamentoBean();
			msg = new FacesMessage(FacesMessage.SEVERITY_INFO, this
					.getServico().getValor("msg_header_sucesso"), this
					.getServico().getValor("msg_sucesso_salva_cotacao"));
			RequestContext.getCurrentInstance().execute("dlgCota.hide()");

			if (codigo.get("UPDATE") != null) {
				this.compradorServico.enviaEmailComprador(
						"Existe uma nova cotação alterada pelo fornecedor",
						"Cotação Alterada.", codigo.get("UPDATE"));
			} else {

				// String teste =
				// "<!DOCTYPE HTML><html lang='en'> <head>  <meta charset='utf-8' />   <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1'>    <link href='https://fonts.googleapis.com/css?family=Limelight|Flamenco|Federo|Yesteryear|Josefin Sans|Spinnaker|Sansita One|Handlee|Droid Sans|Oswald:400,300,700'    media='screen' rel='stylesheet' type='text/css' />    <link href='bootstrap.css' media='screen' rel='stylesheet' type='text/css' />    <link href='bootstrap-responsive.css' media='screen' rel='stylesheet' type='text/css'    />    <link href='fontawesome.css' media='screen' rel='stylesheet' type='text/css' />    <link href='style.css' media='screen' rel='stylesheet' type='text/css' />    <title>Cotasul Email</title>    <style type='text/css'>html {  background-color: #ffffff;}body {  undefined}#page-wrapper {  position: relative;  width: 980px;   margin: 0 auto;  overflow: hidden;  height: 1000px;} body>p, body>h1, body>h2, body>h3, body>h4, body>h5, body>h6 {  margin-top: 0 !important;}.row-fluid .span2.span2-1 {  width: 640px;}.row-fluid .span2.span2-2 {  width: 624px;}.row-fluid {  width: 628px;  position: absolute;  top: 12px;  left: 186px;}.row-fluid .span2 .container-empty {  background: rgba(0, 0, 0, 0) url(image.png) no-repeat 0px 0px;  background-size: auto;  padding: 0px;  width: 622px;  height: 146px;}.row-fluid .span2 .heading {  border: 1px solid #333333;  text-align: center;  font-family:'times new roman';  font-size: 38.66666793823242px;}.row-fluid .span2 p {  text-align: center;  font-size: 18px;  border: 1px solid #333333;}    </style>  </head>     <body>    <div id='page-wrapper'>      <div class='row-fluid'>        <span class='span2 span2-1'>          <span class=''></span>        </span>        <span class='span2 span2-2'>          <h1 class='heading'>Nova Cotação</h1>        </span>        <span class='span2'>          <p>Você recebeu uma nova Cotação.</p>        </span>      </div>    </div>  </body> </html>";
				this.compradorServico.enviaEmailComprador(
						"Existe uma nova cotação.", "Cotação Incluída.",
						codigo.get("INSERT"));
			}
		} catch (MySQLIntegrityConstraintViolationException e1) {
			msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, this
					.getServico().getValor("msg_header_erro"), this
					.getServico().getValor("msg_erro_constraint_fk_violation"));
		} catch (EmailException e2) {
			msg2 = new FacesMessage(FacesMessage.SEVERITY_ERROR, this
					.getServico().getValor("msg_header_erro"), this
					.getServico().getValor("msg_erro_email"));
			e2.printStackTrace();
			FacesContext.getCurrentInstance().addMessage(null, msg2);
		} catch (Exception e3) {
			msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, this
					.getServico().getValor("msg_header_erro"), this
					.getServico().getValor("msg_erro_salva_cotacao"));
			e3.printStackTrace();
		}
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public void cancelar() {

	}

	public boolean comparaData(Date dataValidade) {
		return Ferramentas.comparaDataMaior(
				dataValidade,
				Ferramentas.formataData(Ferramentas.formataData(
						new Date().getTime(), "yyyyMMdd"), "yyyyMMdd"));
	}

	public void validaFormaPag(FacesContext fc, UIComponent ui, Object objeto) {

		/* Map<String, String> param = new HashMap<String, String>(); */
		param.put("CODIGO", objeto.toString());
		param.put("CODFORNE", fornecedor.getCodigo() + "");

		try {
			if (formaServico.buscaFormas(param).size() == 0) {
				msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, this
						.getServico().getValor("msg_header_erro"), this
						.getServico().getValor("msg_valor_invalido"));
				FacesContext.getCurrentInstance().addMessage(null, msg);
				((UIInput) ui).setValid(false);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void filtraOrcamentos() {
		try {
			// orcamentoServico = new OrcamentoServico<OrcamentoBean>();
			orcamento = new OrcamentoBean();
			if (!"".equals(dataDe.trim())) {
				orcamento.setDataEmissao(Ferramentas.formataData(dataDe,
						"dd/MM/yy"));
			}
			if (!"".equals(dataAte.trim())) {
				orcamento.setDataValidade(Ferramentas.formataData(dataAte,
						"dd/MM/yy"));
			}
			if (numero.trim().equals("")) {
				orcamento.setNumero((long) 0);
			} else {
				orcamento.setNumero(Long.parseLong(numero));
			}

			listaOrcamentos = orcamentoServico.filtraOrcamentoFornecedor(
					orcamento, fornecedor);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void preparaImagem(byte[] imagem) {
		try {
			BufferedImage img = ImageIO.read(new ByteArrayInputStream(imagem));
			File file = new File("imagem");
			ImageIO.write(img, "png", file);
			FileInputStream fi = new FileInputStream(file);
			imagemProduto = new DefaultStreamedContent(fi);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void imprimeRelatorioFornecedor() {
		try {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("IDFORNE", fornecedor.getCodigo());
			if (dataDeFiltro != null) {
				param.put("DATADE", dataDeFiltro);
			}
			if (dataAteFiltro != null) {
				param.put("DATAATE", dataAteFiltro);
			}
			param.put("CODCOMPRADOR", compradorFiltro != null ? compradorFiltro
					: null);
			param.put("CODORCAMENTO", orcamentoFiltro);
			param.put("ORDEMFILTRO", ordemFiltro);
			param.put("STATUSORCA", statusFiltro);
			orcamentoServico.imprimeRelatorioOrcamentosFornecedor(
					FacesContext.getCurrentInstance().getExternalContext()
							.getRealPath("/rel/CotacaoPorFornecedor.jasper"),
					FacesContext
							.getCurrentInstance()
							.getExternalContext()
							.getRealPath(
									"/rel/" + "\\cotacao" + usuario.getCodigo()
											+ ".pdf"), param);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void imprimeRelatorioComprador() {
		try {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("CODCOMPRADOR", comprador);
			if (dataDeFiltro != null) {
				param.put("DATADE", dataDeFiltro);
			}
			if (dataAteFiltro != null) {
				param.put("DATAATE", dataAteFiltro);
			}
			param.put("IDFORNE", fornecedorFiltro != null ? fornecedorFiltro
					: null);
			param.put("CODORCAMENTO", orcamentoFiltro);
			param.put("ORDEMFILTRO", ordemFiltro);
			param.put("PRODFILTRO", produtoFiltro != null ? produtoFiltro
					: null);
			param.put("STATUSORCA", statusFiltro);
			orcamentoServico.imprimeRelatorioOrcamentosComprador(
					FacesContext.getCurrentInstance().getExternalContext()
							.getRealPath("/rel/CotacaoPorComprador.jasper"),
					FacesContext
							.getCurrentInstance()
							.getExternalContext()
							.getRealPath(
									"/rel/" + "\\cotacao" + usuario.getCodigo()
											+ ".pdf"), param);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<CompradorBean> completeComprador(String query) {
		List<CompradorBean> sugestoes = null;
		try {
			param.put("NOME", query);
			sugestoes = compradorServico.buscaComprador(param);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sugestoes;
	}

	public List<FornecedorBean> completeFornecedor(String query) {
		List<FornecedorBean> sugestoes = null;
		try {
			param.put("NOME", query);
			sugestoes = fornecedorServico.buscaFornecedor(param);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sugestoes;
	}

	public List<ProdutoBean> completeProduto(String query) {
		List<ProdutoBean> sugestoes = null;
		try {
			param.put("NOMEPROD", query);
			sugestoes = produtoServico.consultaProdutos(null, query, comprador
					.getUsuario().getCodigo());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sugestoes;
	}

	public List<OrcamentoBean> getListaOrcamentos() {
		return listaOrcamentos;
	}

	public void setListaOrcamentos(List<OrcamentoBean> listaOrcamentos) {
		this.listaOrcamentos = listaOrcamentos;
	}

	public UsuarioBean getUsuario() {
		return usuario;
	}

	public void setUsuario(UsuarioBean usuario) {
		this.usuario = usuario;
	}

	public OrcamentoServico<OrcamentoBean> getOrcamentoServico() {
		return orcamentoServico;
	}

	public void setOrcamentoServico(
			OrcamentoServico<OrcamentoBean> orcamentoServico) {
		this.orcamentoServico = orcamentoServico;
	}

	public String getDataDe() {
		return dataDe;
	}

	public void setDataDe(String dataDe) {
		this.dataDe = dataDe;
	}

	public String getDataAte() {
		return dataAte;
	}

	public void setDataAte(String dataAte) {
		this.dataAte = dataAte;
	}

	public String getNumero() {
		return numero;
	}

	public void setNumero(String numero) {
		this.numero = numero;
	}

	public OrcamentoBean getOrcamento() {
		return orcamento;
	}

	public void setOrcamento(OrcamentoBean orcamento) {
		this.orcamento = orcamento;
	}

	public FornecedorBean getFornecedor() {
		return fornecedor;
	}

	public void setFornecedor(FornecedorBean fornecedor) {
		this.fornecedor = fornecedor;
	}

	public CotacaoBean getCotacao() {
		return cotacao;
	}

	public void setCotacao(CotacaoBean cotacao) {
		this.cotacao = cotacao;
	}

	public CotacaoServico<CotacaoBean> getCotacaoServico() {
		return cotacaoServico;
	}

	public void setCotacaoServico(CotacaoServico<CotacaoBean> cotacaoServico) {
		this.cotacaoServico = cotacaoServico;
	}

	public ItemOrcamentoBean getItem() {
		return item;
	}

	public void setItem(ItemOrcamentoBean item) {
		this.item = item;
	}

	public StreamedContent getImagemProduto() {
		return imagemProduto;
	}

	public void setImagemProduto(StreamedContent imagemProduto) {
		this.imagemProduto = imagemProduto;
	}

	public String getTipoFreteInput() {
		return tipoFreteInput;
	}

	public void setTipoFreteInput(String tipoFreteInput) {
		this.tipoFreteInput = tipoFreteInput;
	}

	public CompradorBean getCompradorFiltro() {
		return compradorFiltro;
	}

	public void setCompradorFiltro(CompradorBean compradorFiltro) {
		this.compradorFiltro = compradorFiltro;
	}

	public Date getDataDeFiltro() {
		return dataDeFiltro;
	}

	public void setDataDeFiltro(Date dataDeFiltro) {
		this.dataDeFiltro = dataDeFiltro;
	}

	public Date getDataAteFiltro() {
		return dataAteFiltro;
	}

	public void setDataAteFiltro(Date dataAteFiltro) {
		this.dataAteFiltro = dataAteFiltro;
	}

	public Long getOrcamentoFiltro() {
		return orcamentoFiltro;
	}

	public void setOrcamentoFiltro(Long orcamentoFiltro) {
		this.orcamentoFiltro = orcamentoFiltro;
	}

	public String getOrdemFiltro() {
		return ordemFiltro;
	}

	public void setOrdemFiltro(String ordemFiltro) {
		this.ordemFiltro = ordemFiltro;
	}

	public FornecedorBean getFornecedorFiltro() {
		return fornecedorFiltro;
	}

	public void setFornecedorFiltro(FornecedorBean fornecedorFiltro) {
		this.fornecedorFiltro = fornecedorFiltro;
	}

	public CompradorBean getComprador() {
		return comprador;
	}

	public void setComprador(CompradorBean comprador) {
		this.comprador = comprador;
	}

	public ProdutoBean getProdutoFiltro() {
		return produtoFiltro;
	}

	public void setProdutoFiltro(ProdutoBean produtoFiltro) {
		this.produtoFiltro = produtoFiltro;
	}

	public String getStatusFiltro() {
		return statusFiltro;
	}

	public void setStatusFiltro(String statusFiltro) {
		this.statusFiltro = statusFiltro;
	}

}
